/*
* Need C++ 14 standard.
* g++ -std=c++14 xxx.cpp
*/
#include <iostream>
#include <memory>

// 枚举网格实体
// 应该不用将这个enum放入MeshEntity类
// 不止在MeshEntity中构造
// 这里应该也用命名空间包一层，区分框架
namespace JAUMIN{
enum class MeshEntityEnum : char{
    Cell,
    Face
};
}

namespace JASMIN{
enum class MeshEntityEnum : char{
    XSide,
    Cell_X
};
}

// 接口类
class EntityTypeInterface {
public:
    virtual void print() const = 0;
    virtual ~EntityTypeInterface() = default;
};


// 运行时表示类
// 这里能不能用命令空间来包一层？
// 区分JASMIN和JUSMAR框架
class EntityType {
public:
    // 使用 std::unique_ptr 意味着 EntityType 类拥有了对 EntityTypeInterface 类型对象的所有权。
    // 当 EntityType 对象被销毁时，它将负责释放所拥有的 EntityTypeInterface 对象，从而避免了内存泄漏。
    EntityType(std::unique_ptr<EntityTypeInterface> entity) : entity_(std::move(entity)) {}

    void print() const {
        entity_->print();
    }

private:
    std::unique_ptr<EntityTypeInterface> entity_;
};

// 实现类1 - 网格微元
class MeshEntity : public EntityTypeInterface {
public:
    MeshEntity(int attach_num) : attach_num_(attach_num) {
        std::cout << "Constru in MeshEntity" << std::endl;
    }

    MeshEntity(JAUMIN::MeshEntityEnum meshtype): jau_meshtype_(meshtype){
        std::cout << "Construct JAUMIN mesh entity" << std::endl; 
    }

    MeshEntity(JASMIN::MeshEntityEnum meshtype): jas_meshtype_(meshtype){
        std::cout << "Construct JAUMIN mesh entity" << std::endl; 
    }

    MeshEntity(JAUMIN::MeshEntityEnum meshtype, int attach_num) : jau_meshtype_(meshtype),attach_num_(attach_num) {
        // std::cout << "MeshEntityEnum: " << meshtype << std::endl;
        std::cout << "attach_num: " << attach_num << std::endl;
    }



    void print() const override {
        std::cout << "Mesh Entity num: " << attach_num_ << std::endl;
    }

private:
    int attach_num_;
    JAUMIN::MeshEntityEnum jau_meshtype_;
    JASMIN::MeshEntityEnum jas_meshtype_;
};

// 实现类2 - 附属微元
class AttachEntity : public EntityTypeInterface {
public:
    AttachEntity(int attach_num) : attach_num_(attach_num) {
        std::cout << "Constru in AttachEntity" << std::endl;
    }

    void print() const override {
        std::cout << "Attachment Entity: " << attach_num_ << std::endl;
    }

private:
    int attach_num_;
};

// 这个例子会导致写很多的子类，很多的构造函数
// 尝试RTType类似的类型管理器？ 类型系统？

int main() {

    EntityType entity1(std::make_unique<MeshEntity>(42));
    EntityType entity2(std::make_unique<AttachEntity>(10));
    EntityType entity3(std::make_unique<MeshEntity>(JAUMIN::MeshEntityEnum::Cell,5));
    entity3.print();
    entity1.print();
    entity2.print();

    EntityType entity4(std::make_unique<MeshEntity>(JASMIN::MeshEntityEnum::Cell_X));
    entity4.print();

    return 0;
}
